package com.ccn.crm.util;

import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import com.ccn.crm.model.MailBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailSendException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class EmailUtil {

    @Autowired
    private JavaMailSender mailSender; // 自动注入的Bean

    @Value("${spring.mail.username}")
    private String sender; // 读取配置文件中的参数

    /**
     * 发送邮件测试方法
     */
    public void sendMail(String text) {

            SimpleMailMessage mimeMessage = new SimpleMailMessage();
            mimeMessage.setFrom(sender);
            String[] cc = {"xiangyang.wang@yesno.com.cn", "guojizhen@yesno.com.cn", "hooverhuang@yesno.com.cn"};
//         mimeMessage.setTo("xiangyang.wang@yesno.com.cn");
            mimeMessage.setTo(cc);
            mimeMessage.setSubject("crm--禅道接口异常");
            mimeMessage.setText(text);
            mailSender.send(mimeMessage);

    }
    /**
     * 发送邮件测试方法
     */
    public void sendMailMe(String text) {

        SimpleMailMessage mimeMessage = new SimpleMailMessage();
        mimeMessage.setFrom(sender);
        String[] cc = {"xiangyang.wang@yesno.com.cn"};

//         mimeMessage.setTo("xiangyang.wang@yesno.com.cn");
        mimeMessage.setTo(cc);
        mimeMessage.setSubject("crm--禅道接口异常");
        mimeMessage.setText(text);
        mailSender.send(mimeMessage);
    }
    /**
     * 发送简易邮件
     * @param mailBean
     */
    public void sendMail(MailBean mailBean) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

        try {
            helper.setFrom(sender);
            helper.setTo(mailBean.getReceiptPeople());
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }


    }
    /**
     * 发送简易邮件
     * @param mailBean
     */
    public void sendMailManyPro(MailBean mailBean,String[]sent) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

        try {
            helper.setFrom(sender);
            helper.setTo(sent);
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }


    }

    /**
     * 发送邮件-邮件正文是HTML发送多人，抄送多人
     * @param mailBean
     */
    public void sendMailHtml(MailBean mailBean,String[] sent,String[] cc) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

        try {
            helper.setFrom(sender);
//           helper.setTo("xiangyang.wang@yesno.com.cn");
            helper.setTo(sent);
            helper.setCc(cc);
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText(), true);
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            String[] invalid = getInvalidAddresses(e);
            if (invalid != null) {
                this.sendMailHtml(mailBean,filterByArray(sent, invalid), filterByArray(cc, invalid));
            }
        }
    }

    /**
     * 发送邮件-邮件正文是HTML发送多人，抄送多人
     * @param mailBean
     */
    public void sendMailHtml(MailBean mailBean,String[] cc) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

        try {
            helper.setFrom(sender);
//           helper.setTo("xiangyang.wang@yesno.com.cn");
//            helper.setTo(mailBean.getReceiptPeople());
            helper.setCc(cc);
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText(), true);
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            String[] invalid = getInvalidAddresses(e);
            if (invalid != null) {
                this.sendMailHtml(mailBean, filterByArray(cc, invalid));
            }
        }
    }
    /**
     * 发送邮件-邮件正文是HTML发送多人，抄送多人
     * @param mailBean
     */
    public void sendMailHtmlByOne(MailBean mailBean,String sent) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);

        try {
            helper.setFrom(sender);
            helper.setTo(sent);
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText(), true);
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 发送邮件-附件邮件
     * @param mailBean
     */
    public void sendMailAttachment(MailBean mailBean) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(sender);
            helper.setTo(sender);
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText(), true);
            // 增加附件名称和附件
            helper.addAttachment(mailBean.getAttachmentFilename(), mailBean.getFile());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 内联资源（静态资源）邮件发送
     * 由于邮件服务商不同，可能有些邮件并不支持内联资源的展示
     * 在测试过程中，新浪邮件不支持，QQ邮件支持
     * 不支持不意味着邮件发送不成功，而且内联资源在邮箱内无法正确加载
     * @param mailBean
     */
    public void sendMailInline(MailBean mailBean) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(sender);
            helper.setTo(sender);
            helper.setSubject(mailBean.getSubject());

            /*
             * 内联资源邮件需要确保先设置邮件正文，再设置内联资源相关信息
             */
            helper.setText(mailBean.getText(), true);
            helper.addInline(mailBean.getContentId(), mailBean.getFile());

            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 模板邮件发送
     * @param mailBean
     */
    public void sendMailTemplate(MailBean mailBean) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom(sender);
            helper.setTo(sender);
            helper.setSubject(mailBean.getSubject());
            helper.setText(mailBean.getText(), true);
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
    /**
     * 从异常获取无效地址
     * @param e
     * @return
     */
    private static String[] getInvalidAddresses(Throwable e) {
        if (e == null) {
            return null;
        }
        if (e instanceof MailSendException) {
            System.out.println("e instanceof SendFailedException");
            Exception[] exceptions = ((MailSendException) e).getMessageExceptions();
            for (Exception exception : exceptions) {
                if (exception instanceof SendFailedException) {
                    return getStringAddress(((SendFailedException) exception).getInvalidAddresses());
                }
            }
        }
        if (e instanceof SendFailedException) {
            return getStringAddress(((SendFailedException) e).getInvalidAddresses());
        }
        return null;
    }

    /**
     * 将Address[]转成String[]
     * @param address
     * @return
     */
    private static String[] getStringAddress(Address[] address) {
        List<String> invalid = new ArrayList<>();
        for (Address a : address) {
            String aa = ((InternetAddress) a).getAddress();
            if (!StringUtils.isEmpty(aa)) {
                invalid.add(aa);
            }
        }
        return invalid.stream().distinct().toArray(String[]::new);
    }
    /**
     * 过滤数组source，规则为数组元素包含了数组filter中的元素则去除
     *
     * @param source
     * @param filter
     * @return
     */
    private static String[] filterByArray(String[] source, String[] filter) {
        List<String> result = new ArrayList<>();
        for (String s : source) {
            boolean contains = false;
            for (String f : filter) {
                if (s.contains(f)) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                result.add(s);
            }
        }
        return result.stream().toArray(String[]::new);
    }
}